package tool.soft

import java.io.File
import akka.stream.Materializer
import dao._
import implicits.Implicits._
import models.Tables
import models.Tables._
import org.joda.time.DateTime
import play.api.data.FormBinding
import play.api.libs.ws.WSClient
import play.api.mvc.{AnyContent, Request}
import play.twirl.api.Html
import shared.Pojo._
import tool.Pojo._
import tool.plot._
import tool.soft.AllSoft.SoftBT
import tool.softT.RfSoftBT
import tool._

import scala.language.postfixOps
import play.api.i18n.Messages
import utils.Utils
import upickle.default._

/**
 * Created by yz on 15/9/2020
 */
object RfSoft extends RfSoftBT with SoftBT {

  override def resultDeal(workspaceDir: File, resultDir: File)(implicit ws: WSClient, materializer: Materializer): Unit = {
    Tool.resultDeal(workspaceDir, resultDir)
  }

   override def produceConfigFile(workspaceDir: File,index:Int)(implicit request: Request[AnyContent], formBinding: FormBinding) = {
    super.produceConfigFile(workspaceDir,index)
    Utils.t2ConfigFile(workspaceDir,data)
     Utils.t2ConfigFile(data, Tool.getCalculateConfigJsonFile(workspaceDir))
  }

  override def getResultHtml(missionId: Int)(implicit request: Request[AnyContent], messages: Messages): Html = {
    views.html.user.mission.rfResult(missionId)
  }

  def getArg(implicit request: Request[AnyContent], messages: Messages, formBinding: FormBinding): ujson.Value = {
    val mtryArg = if (data.hasMtry) {
      ujson.Obj(messages("variablesNumber") -> data.mtry)
    } else ujson.Obj()
    val nodesizeArg = if (data.hasNodesize) {
      ujson.Obj(messages("nodesMinimumSize") -> data.nodesize)
    } else ujson.Obj()
    val maxnodesArg = if (data.hasMaxnodes) {
      ujson.Obj(messages("nodesMaximumNumber") -> data.maxnodes)
    } else ujson.Obj()
    val scaleMethodMap=Tool.getScaleMethodMap
    ujson.Obj(messages("scaleMethod") ->scaleMethodMap(data.scaleMethod),messages("numberOfTreesToGrow") -> data.ntree, messages("samplingWithReplacement") -> Tool.getTFStr(data.replace), messages("selectionTopM") -> data.topM) ++
      mtryArg ++ nodesizeArg ++ maxnodesArg
  }

  override def getHtml(missionName: String, missionId: Option[Int])(implicit request: Request[AnyContent], messages: Messages): Html = {
    views.html.user.soft.rf(missionName, missionId)
  }

  override def getMission(implicit request: Request[AnyContent], matrixFileDataDao: MatrixFileDataDao, messages: Messages, formBinding: FormBinding): Tables.MissionRow = {
    val initInput = List(data.file, data.groupFile)
    val argJson = getArg
    MissionRow(id = 0, missionName = s"${data.missionName}", kind = nameStr, userId = userId,
      startTime = new DateTime(), state = "preparing", arg = argJson, input = initInput)
  }

  override def produceInputFile(workspaceDir: File)(implicit request: Request[AnyContent], dao: MyDao, formBinding: FormBinding): Any = {
    val rawDataFile = new File(workspaceDir, "AllMet_Raw.txt")
    Tool.produceRawMetaboliteFile(userId, data.file, rawDataFile)

    val originalGroupFile = new File(workspaceDir, "group.txt")
    Tool.produceRawGroupFile(userId, data.groupFile, rawDataFile, originalGroupFile)

  }

  override def data(implicit request: Request[AnyContent], formBinding: FormBinding) = {
    FormTool.rfForm.bindFromRequest().get
  }

  override def getCommandData(workspaceDir: File, resultDir: File, index: Int): List[CommandData] = {
    val solutionFile = new File(Tool.dataDir, "color_solution/color_solution_1.txt")
    val rawDataFile = new File(workspaceDir, "AllMet_Raw.txt")
    val standardFile = Tool.getStandardFile(workspaceDir)
    val inputMetabolites=Tool.inputMetabolites(workspaceDir)
    val command =if(inputMetabolites.nonEmpty) {
      s"""
         |${"Rscript".condaPath()} ${Tool.rPath.unixPath}/standard.R
         |${"Rscript".condaPath()} ${new File(Tool.rPath, "rf_calculate.R").unixPath} --i ${standardFile.unixPath}
         |${"Rscript".condaPath()} ${new File(Tool.rPath, "rf_plot.R").unixPath} --pc ${RfPlot.configFileName}
         |convert  -density 300 RF_Imp.pdf  RF_Imp.png
         |${"Rscript".condaPath()} ${new File(Tool.rPath, "rf_filter.R").unixPath}
           """.stripMargin
    }else ""
    List(CommandData(workspaceDir, List(command)))
  }


}

